<template>
    <div>
        <el-header>
            <el-breadcrumb separator="/">
                <el-breadcrumb-item :to="{ path: '/' }"><el-icon><House /></el-icon></el-breadcrumb-item>
                <el-breadcrumb-item :to="{ path: '/depmapExplore' }">Depmap Explore Data</el-breadcrumb-item>
                <el-breadcrumb-item>Detail</el-breadcrumb-item>
                <el-breadcrumb-item>Target: {{ route.params.Target }}</el-breadcrumb-item>
                <el-breadcrumb-item>Tumor-Type: {{ route.params.TumorType }}</el-breadcrumb-item>
            </el-breadcrumb>
        </el-header>
        <div class="container" v-loading="loading">
            <div class="table-container">
                <el-table 
                    :data="tableData" 
                    height="450"
                    stripe
                    @sort-change="handleSortChange"
                >
                    <el-table-column prop="name" label="DepmapID" show-overflow-tooltip width="150" sortable />
                    <el-table-column prop="StrippedCellLineName" label="CellLine" show-overflow-tooltip sortable />
                    <el-table-column prop="OncotreeLineage" label="OncotreeLineage" width="170" show-overflow-tooltip sortable />
                    <el-table-column prop="OncotreePrimaryDisease" label="OncotreePrimaryDisease" show-overflow-tooltip width="250" sortable />
                    <el-table-column prop="OncotreeSubtype" label="OncotreeSubtype" show-overflow-tooltip width="250" sortable />
                    <el-table-column :prop="route.params.Target" :label=getSwitchName() :formatter="formatDecimal"  width="200" sortable />
                    <el-table-column prop="isecDNA" label="Group" sortable>
                        <template #default="scope">
                            <span v-if="scope.row.isecDNA == '0'">ecDNA-</span>
                            <span v-else-if="scope.row.isecDNA == '1'">ecDNA+</span>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
            <div class="select-container">
                <el-select-v2
                    class="select-bar"
                    v-model="selectedChart"
                    :options="chartOptions"
                    placeholder="Please select chart"
                    @change="handleSelectChange"
                    size="large"
                    style="width: 240px"
                    />
            </div>
            <div class="chart-container" :style="{display: 'flex', flexDirection: flexDirection}">
                <div class="chart">
                    <v-chart class="colChart" :option="columnOption" autoresize  ></v-chart>
                </div> 
                <div v-if="selectedChart === 'violin'" id="violinPlot"></div>
                <div v-else class="chart">
                    <v-chart class="colChart" :option="averageOption" autoresize  ></v-chart>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup name="DepDetail">
    import { onBeforeMount, onMounted, ref, nextTick, watch } from 'vue';
    import { useRoute } from 'vue-router';
    import { get, post } from '../../axios/api';
    import { ElMessage, } from 'element-plus'
    import Plotly from 'plotly.js-dist'
    import VChart, { THEME_KEY } from 'vue-echarts';
    import { averageOption, columnOption } from './columnOption'

    let loading = ref(false)
    const route = useRoute()
    let tableData: any = ref([])
    let dataType: any = ref('')
    let flexDirection:any = ref('row')

    let isSorted = ref(false)
    let sortedProp = ref('name')
    let sortedOrder = ref('ascending')
    let showViolin = ref(true)

    let selectedChart = ref('violin')
    let resultData:any = ref(null)

    const chartOptions = ref([
        {
            value: 'violin',
            label: 'Show Violin Chart'
        },
        {
            value: 'bar',
            label: 'Show Bar Chart'
        }
    ])

    async function handleSortChange(ele:any) {
        isSorted.value = true
        sortedProp.value = ele.prop.split('.')[1]
        sortedOrder.value = ele.order
        get_violin_data(sortedProp.value, sortedOrder.value)
    }


    function formatDecimal(row:any, column:any, cellValue:any) {
        let res = null;
        if (typeof cellValue === 'number') {
            // 判断小数部分是否为0
            if (cellValue % 1 === 0) {
                res = cellValue.toFixed(0); // 如果是整数，则不保留小数部分
            } else {
                res = parseFloat(cellValue.toFixed(8)); // 保留6位小数
            }
        } else if (typeof cellValue === 'string') {
            res = cellValue.slice(0, 9);
        }
        return res;
    }

    async function get_violin_data(sort_by: any, sort_order: any) {
        loading.value = true
        let params = {
            target: route.params.Target,
            tumor_type: route.params.TumorType,
            data_type: dataType.value,
            sort_by,
            sort_order
        }
        let res: any = await post('/get_violin_data/', params)
        if (res && res.success) {
            loading.value = false
            tableData.value = [...res.data.ecDNA_plus, ...res.data.ecDNA_minus]
            showViolin.value = false
            averageOption.value.series[0].data = [res.data.plus_average]
            averageOption.value.series[1].data = [res.data.minus_average]
            averageOption.value.title.text = getSwitchName()
            resultData.value = res.data
            plotViolinChart(res.data)

            const xAxisData = res.data.categories;
            const yAxisData1 = xAxisData.map((cat: any) => res.data.chart_data[cat].ecDNA_plus);
            const yAxisData2 = xAxisData.map((cat: any) => res.data.chart_data[cat].ecDNA_minus);
            columnOption.value.xAxis.data = xAxisData
            columnOption.value.series[0].data = yAxisData1
            columnOption.value.series[1].data = yAxisData2
            let len = res.data.categories.length
            flexDirection.value = len > 10 ? 'column' : 'row'
            if (len <= 5) {
                // columnOption.value.grid.width = '50%'; // 拉宽整体图表
                columnOption.value.series[0].barGap = '200%'; // 同组柱间距
                columnOption.value.xAxis.axisLabel.rotate = 0
                columnOption.value.series[0].barCategoryGap = '30%'; // 组间间距
            } else {
                columnOption.value.grid.width = 'auto'; // 恢复默认宽度
                columnOption.value.series[0].barGap = '0';
                // columnOption.value.series[0].barCategoryGap = '20%';
                columnOption.value.xAxis.axisLabel.rotate = 40
            }
            columnOption.value.series[0].barWidth = len < 10 ? '32px' : 'auto';
            columnOption.value.series[1].barWidth = len < 10 ? '32px' : 'auto';
        } else {
            loading.value = false
            ElMessage({
                message: "An error occured",
                type: 'error',
            })
        }
    }

    function plotViolinChart(data: any) {
        // 小提琴图数据
        nextTick(() => {
            const trace1:any = {
                x: Array(data.y1.length).fill(1),
                y: data.y1,
                type: 'violin',
                name: 'ecDNA+',
                box: { visible: true },
                meanline: { visible: true },
                line: { color: '#E41A1C' },
                fillcolor: 'rgba(0,0,0,0)',
                hoverinfo: 'skip',
                showlegend: false
            };

            const trace2:any = {
                x: Array(data.y2.length).fill(2),
                y: data.y2,
                type: 'violin',
                name: 'ecDNA-',
                box: { visible: true },
                meanline: { visible: true },
                line: { color: '#377EB8' },
                fillcolor: 'rgba(0,0,0,0)',
                hoverinfo: 'skip',
                showlegend: false
            };

            const hovertemplateCategory1 = generateHoverTemplate(data.ecDNA_plus);
            const hovertemplateCategory2 = generateHoverTemplate(data.ecDNA_minus);

            const x1 = Array(data.y1.length).fill(1).map(x => jitter(x));
            const x2 = Array(data.y2.length).fill(2).map(x => jitter(x));

            // 散点图数据
            const scatter1:any = {
                x: x1,
                y: data.y1,
                mode: 'markers',
                name: 'ecDNA+',
                marker: { color: '#E41A1C' },
                hovertemplate: hovertemplateCategory1,
                type: 'scatter',
                showlegend: false
            };

            const scatter2:any = {
                x: x2,
                y: data.y2,
                mode: 'markers',
                name: 'ecDNA-',
                marker: { color: '#377EB8' },
                hovertemplate: hovertemplateCategory2,
                type: 'scatter',
                showlegend: false
            };
            let yTitle: any = getSwitchName()
            const layout:any = {
                xaxis: {
                    tickvals: [1, 2],
                    ticktext: ['ecDNA+', 'ecDNA-'],
                    zeroline: true, // 显示 x 轴的零线
                    showline: true, // 显示 x 轴的线
                    linecolor: 'black', // x 轴线的颜色
                    linewidth: 2 // x 轴线的宽度
                },  // x轴刻度值与文本
                yaxis: {
                    title: yTitle,
                    zeroline: false, // 显示 y 轴的零线
                    showline: true, // 显示 y 轴的线
                    linecolor: 'black', // y 轴线的颜色
                    linewidth: 2, // y 轴线的宽度
                },
                hovermode: 'closest',
            };

            // 绘制小提琴图和散点图
            Plotly.newPlot('violinPlot', [trace1, trace2, scatter1, scatter2], layout);
        })
    }

    const jitter = (base: number, range = 0.15) => base + (Math.random() - 0.5) * range;

    const getSwitchName = () => {
        let key = route.params.dataType
        switch (key) {
            case 'depmap_diff_protein_analysis':
                key = 'Protein expression level'
            case 'depmap_diff_drug_analysis':
                key = 'Log2-FC between treatment and control'
            case 'depmap_diff_gene_analysis':
                key = 'Crispr gene effect value'
            case 'depmap_diff_expression_analysis':
                key = 'Gene expression'
            case 'depmap_diff_methylation_analysis':
                key = 'Methylation'
        }
        return key
    }

    const generateHoverTemplate = (categoryData: any) => {
        let itemKey: any = getSwitchName()

        return categoryData.map((item: any) => {
            let hoverText = '';
            for (const [key, value] of Object.entries(item)) {
                if (key === route.params.Target) {
                    hoverText += `${itemKey}: ${value}<br>`;
                } else if (key ==='name') {
                    hoverText += `DepmapID: ${value}<br>`;
                } else if (key === 'isecDNA')  {
                    continue
                } else {
                    hoverText += `${key}: ${value}<br>`;
                }
            }
            return hoverText;
        });
    };

    function handleSelectChange(value: any) {
        selectedChart.value = value
    }

    watch(selectedChart, (newVal) => {
        if (newVal === 'violin') {
            plotViolinChart(resultData.value)
        }
    });


    onBeforeMount(() => {
        dataType.value = route.params.dataType
        switch (dataType.value) {
            case 'depmap_diff_expression_analysis':
                dataType.value = 'Exp'
                break
            case 'depmap_diff_protein_analysis':
                dataType.value = 'Protein'
                break
            case 'depmap_diff_drug_analysis':
                dataType.value = 'Drug'
                break
            case 'depmap_diff_gene_analysis':
                dataType.value = 'Gene'
                break
            case 'depmap_diff_methylation_analysis':
                dataType.value = 'Methylation'
                break
            default:
                dataType.value = 'None'
                break
        }
        get_violin_data(sortedProp.value, sortedOrder.value)
    })

</script>

<style lang="scss" scoped>
    #violinPlot {
        display: flex;
        justify-content: space-around;
        width: 100%;
        height: 65vh;
        border-radius: 4px;
    }

    .container {
        width: 100%;
        display: block;
    }

    .table-container {
        width: 100%;
        display: block;
        padding: 4px;
        border-radius: 4px;
        background-color: white;
        margin: 20px 0;
    }
    
    .chart-container {
        width: 100%;
        display: flex;
        justify-content: flex-start;
        padding: 20px 0;
    }

    .select-container {
        width: 100%;
        .select-bar {
            display: block;
            width: 100%;
            float: right;
        }
    }
    
    .chart {
        height: 50vh;
        width: 100%;
        padding-top: 10%;
        margin-bottom: 100px;
        margin-right: 20px;
        background-color: white;
        border-radius: 4px;
        .colChart {
            height: 50vh;
            width: 100%;
        }
    }
</style>